Android TV开发总结【RecycleView】

在TV开发中RecycleView的使用是最让人头疼的经常会出现焦点丢失。因为当item未显示时不能获取焦点。所以当我们按上下键时经常丢失焦点或者焦点乱跳。要解决这个问题我们必须要手动控制RecyclerView 的按键和焦点移动。

所以我们这里需要需要自定义RecycleView。

代码如下,各个方法作用在注视中已添加:

public class TvRecyclerView extends RecyclerView
{
    //正常跟随滚动
    private static final int SCROLL_NORMAL = 0;
    //居中滚动
    private static final int SCROLL_FOLLOW = 1;

    //滚动模式
    private int scrollModel;

    //当前选中的position
    private int mSelectedPosition = 0;

    //下一个聚焦的View
    private View mNextFocused;

    public TvRecyclerViewNew(Context context)
    {
        this(context, null);
    }

    public TvRecyclerViewNew(Context context, AttributeSet attrs)
    {
        this(context, attrs, -1);
    }

    public TvRecyclerViewNew(Context context, AttributeSet attrs, int defStyle)
    {
        super(context, attrs, defStyle);
        init(context, attrs, defStyle);
    }

    /**
     * 初始化
     *
     * @param context
     * @param attrs
     * @param defStyle
     */
    private void init(Context context, AttributeSet attrs, int defStyle)
    {
        initView();

        initAttr(attrs);
    }

    /**
     * 初始化View
     * 为避免recycleview焦点混乱常用的一些设置
     */
    private void initView()
    {
        setDescendantFocusability(FOCUS_AFTER_DESCENDANTS);
        setHasFixedSize(true);
        setWillNotDraw(true);
        setOverScrollMode(View.OVER_SCROLL_NEVER);
        setChildrenDrawingOrderEnabled(true);

        setClipChildren(false);
        setClipToPadding(false);

        setClickable(false);
        setFocusable(true);
        setFocusableInTouchMode(true);
        /**
         防止RecyclerView刷新时焦点不错乱bug的步骤如下:
         (1)adapter执行setHasStableIds(true)方法
         (2)重写getItemId()方法,让每个view都有各自的id
         (3)RecyclerView的动画必须去掉
         */
        setItemAnimator(null);
    }

    /**
     * 初始化样式
     * 是否居中滚动
     * @param attrs
     */
    private void initAttr(AttributeSet attrs)
    {
        TypedArray typeArray = getContext().obtainStyledAttributes(attrs, R.styleable.TvRecyclerView);
        scrollModel = typeArray.getInteger(R.styleable.TvRecyclerView_scrollMode, 0);
    }

    /**
     * 恢复回收之前的状态
     * @param state
     */
    @Override
    protected void onRestoreInstanceState(Parcelable state)
    {
        Bundle bundle = (Bundle) state;
        Parcelable superData = bundle.getParcelable("super_data");
        super.onRestoreInstanceState(superData);
        setItemSelected(bundle.getInt("select_pos", 0));
    }

    /**
     * 回收之前保存状态
     * @return
     */
    @Override
    protected Parcelable onSaveInstanceState()
    {
        Bundle bundle = new Bundle();
        Parcelable superData = super.onSaveInstanceState();
        bundle.putParcelable("super_data", superData);
        bundle.putInt("select_pos", mSelectedPosition);
        return bundle;
    }

    /**
     * 解决4.4版本抢焦点的问题
     * @return
     */
    @Override
    public boolean isInTouchMode()
    {
        if (Build.VERSION.SDK_INT == 19)
        {
            return !(hasFocus() && !super.isInTouchMode());
        } else
        {
            return super.isInTouchMode();
        }
    }

    @Override
    public void requestChildFocus(View child, View focused)
    {
        super.requestChildFocus(child, focused);
    }

    @Override
    public boolean requestChildRectangleOnScreen(View child, Rect rect, boolean immediate)
    {
        final int parentLeft = getPaddingLeft();
        final int parentRight = getWidth() - getPaddingRight();

        final int parentTop = getPaddingTop();
        final int parentBottom = getHeight() - getPaddingBottom();

        final int childLeft = child.getLeft() + rect.left;
        final int childTop = child.getTop() + rect.top;

        final int childRight = childLeft + rect.width();
        final int childBottom = childTop + rect.height();

        final int offScreenLeft = Math.min(0, childLeft - parentLeft);
        final int offScreenRight = Math.max(0, childRight - parentRight);

        final int offScreenTop = Math.min(0, childTop - parentTop);
        final int offScreenBottom = Math.max(0, childBottom - parentBottom);


        final boolean canScrollHorizontal = getLayoutManager().canScrollHorizontally();
       
  • 3
    点赞
  • 9
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值